﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SiyinPractice.Interface.AccessControl;
using SiyinPractice.Interface.Maintenance;
using SiyinPractice.Interface.ProjectManagement.ProjectManage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace SiyinPractice.Application.ProjectManagement.ProjectManage.Help
{
    /// <summary>
    /// 钉钉服务类
    /// </summary>
    public class DingDingMsgReminderService : BackgroundService
    {
        private readonly IConfiguration _config;

        private readonly ILogger<DingDingMsgReminderService> _logger;

        private readonly IServiceProvider _serviceProvider;

        private DingDingTimeCycleHelper _timeCycleHelper { get; set; }
        private int DefaultTimerInterval;

        private int OldDefaultTimerInterval;

        private int defaultTimer = 7200;
        //   private Test _test;

        public DingDingMsgReminderService(IConfiguration config, DingDingTimeCycleHelper timeCycleHelp, ILogger<DingDingMsgReminderService> logger, IServiceProvider serviceProvider

            )
        {
            this._config = config;
            this._logger = logger;
            this._timeCycleHelper = timeCycleHelp;
            this._serviceProvider = serviceProvider;
        }

        public async void ServiceDo()
        {
            //...需要执行的任务代码

            using var scope = _serviceProvider.CreateScope();
            var _projectSettlement = scope.ServiceProvider.GetRequiredService<IAccountPasswordService>();
            var _DingDingService = scope.ServiceProvider.GetRequiredService<IDingDingService>();
            var _userAppService = scope.ServiceProvider.GetRequiredService<IUserAppService>();
            var list = await _projectSettlement.GetAccountPasswordDto("钉钉");
            var template = await _DingDingService.GetAllAsync();
            var userDtos = _userAppService.GetAllAsync();
            var parentTemplate = await _DingDingService.GetParentSetting();
            if (template != null && parentTemplate != null)
            {
                DefaultTimerInterval = (int)(parentTemplate?.DefaultTimerInterval > 0 ? parentTemplate?.DefaultTimerInterval * 1000 : 3600 * 1000);
                if (OldDefaultTimerInterval != DefaultTimerInterval)
                {
                    OldDefaultTimerInterval = DefaultTimerInterval;
                    this._timeCycleHelper.Stop();
                    this._timeCycleHelper.Start(DefaultTimerInterval, new TimeCycle(new Guid(), this.ServiceDo));
                    this._logger.LogInformation("修改定时器时间");
                }
                else
                {
                    foreach (var item in list)
                    {
                        var now = DateTime.Now;
                        if (now > item.ReminderTime)
                        {
                            TimeSpan ts = now - Convert.ToDateTime(item.ReminderTime);  //计算时间差

                            var seconds = ts.TotalSeconds;  //将时间差转换为秒
                                                            // var hour = (Convert.ToDateTime(item.EndTime) - Convert.ToDateTime(item.ReminderTime)).TotalHours;   //将时间差转换为秒
                            var hour = Convert.ToDouble((Convert.ToDateTime(item.EndTime) - Convert.ToDateTime(item.ReminderTime)).TotalHours).ToString("0.00");
                            //var deefaultTimer = (DefaultTimerInterval / 1000);

                            if (!string.IsNullOrEmpty(item.ReminderTemplate))
                            {
                                var msgreminder = template.FirstOrDefault(x => Convert.ToString(x.Id) == item.ReminderTemplate);
                                if (msgreminder != null)
                                {
                                    defaultTimer = (int)(parentTemplate?.DefaultTimer > 0 ? parentTemplate?.DefaultTimer : 7200);
                                    if ((seconds) < defaultTimer)
                                    {
                                        TextModel textModel2 = new TextModel();
                                        var AccountName = item.AccountName;
                                        var ReminderTime = item.ReminderTime.ToString();
                                        var WebsiteUrl = item.WebsiteUrl;
                                        //此处文本 支持超链接

                                        var templatetext = msgreminder.Content;
                                        templatetext = templatetext.Replace("{" + "AccountName}", AccountName);
                                        templatetext = templatetext.Replace("{" + "Hour}", hour);
                                        templatetext = templatetext.Replace("{" + "ReminderTime}", ReminderTime);
                                        templatetext = templatetext.Replace("{" + "WebsiteUrl}", WebsiteUrl);
                                        textModel2.content = templatetext;
                                        DingDingMsgModel dingDing = new DingDingMsgModel();
                                        dingDing.userid_list = msgreminder.UserId_List;
                                        dingDing.agent_id = parentTemplate.Agent_id;
                                        string dept_id_list = "";
                                        string usernames = "";
                                        string Dept_Id_Lists = msgreminder.Dept_Id_List;
                                        foreach (var user in userDtos)
                                        {
                                            if (Dept_Id_Lists.Split("|").FirstOrDefault(x => x == Convert.ToString(user.DeptId)) != null && !string.IsNullOrEmpty(user.DingDing))
                                            {
                                                dept_id_list = dept_id_list + user.DingDing + ",";
                                            }
                                        }
                                        if (dept_id_list != "")
                                        {
                                            dept_id_list = dept_id_list + dingDing.userid_list;
                                        }
                                        //dept_id_list.Split(",").Distinct();

                                        //string str = string.Join(",", array);

                                        dingDing.userid_list = string.Join(",", dept_id_list.Split(",").Distinct());
                                        // dingDing.dept_id_list = msgreminder.Dept_Id_List;
                                        dingDing.to_all_user = msgreminder.To_All_User;

                                        BodyModel bodyModel = new BodyModel();
                                        bodyModel.title = msgreminder.Title;
                                        bodyModel.content = templatetext;

                                        OaModel oaModel = new OaModel();
                                        oaModel.body = bodyModel;

                                        MsgModel msgModel = new MsgModel();
                                        msgModel.text = textModel2;
                                        msgModel.oa = oaModel;
                                        msgModel.msgtype = msgreminder.Msgtype;

                                        dingDing.msg = msgModel;
                                        SendToDingDing(parentTemplate.Appkey, parentTemplate.Appsecret, dingDing);
                                        await _projectSettlement.UpdateAccountPassword(item.Id.Value);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        public override Task StartAsync(CancellationToken cancellationToken)
        {
            this._logger.LogInformation($"定时任务：钉钉服务已启动...");
            // this.Init(scope);
            DefaultTimerInterval = 660 * 1000; //789
            OldDefaultTimerInterval = DefaultTimerInterval;
            this._timeCycleHelper.Start(DefaultTimerInterval, new TimeCycle(new Guid(), this.ServiceDo));
            return Task.CompletedTask;
        }

        public override Task StopAsync(CancellationToken cancellationToken)
        {
            this._logger.LogInformation($"同步服务已停止...");
            this._timeCycleHelper.Stop();
            return Task.CompletedTask;
        }

        public string SendToDingDing(string appkey, string appsecret, DingDingMsgModel dingDingMsgModel)
        {
            string getTokenUrl = "https://oapi.dingtalk.com/gettoken?appkey=" + appkey + "&appsecret=" + appsecret;
            string str = HttpClientHelper.GetResponse(getTokenUrl);
            Dictionary<string, string> jobject = JsonConvert.DeserializeObject<Dictionary<string, string>>(str);
            if (jobject["errcode"].ToString() == "0" && jobject["errmsg"].ToString() == "ok")
            {
                string token = jobject["access_token"].ToString();

                string postUrl = "https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=" + token;
                string result = HttpClientHelper.PostResponse(postUrl, JsonConvert.SerializeObject(dingDingMsgModel));
                this._logger.LogInformation(JsonConvert.SerializeObject(dingDingMsgModel));
                this._logger.LogInformation(result);
            }
            return "-1";
        }

        //public string GetAccessToken(string corpid, string corpsecret)
        // {
        // }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            try
            {
                while (!stoppingToken.IsCancellationRequested)
                {
                    //string joke = _jokeService.GetJoke();
                    _logger.LogWarning("{Joke}", "111");

                    await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "{Message}", ex.Message);

                // Terminates this process and returns an exit code to the operating system.
                // This is required to avoid the 'BackgroundServiceExceptionBehavior', which
                // performs one of two scenarios:
                // 1. When set to "Ignore": will do nothing at all, errors cause zombie services.
                // 2. When set to "StopHost": will cleanly stop the host, and log errors.
                //
                // In order for the Windows Service Management system to leverage configured
                // recovery options, we need to terminate the process with a non-zero exit code.
                Environment.Exit(1);
            }
        }
    }
}